/*
 * The tee command reads its standard input until end-of-file, writing a copy of the input
 * to standard output and to the file named in its command-line argument. (We show
 * an example of the use of this command when we discuss FIFOs in Section 44.7.)
 * Implement tee using I/O system calls. By default, tee overwrites any existing file with
 * the given name. Implement the –a command-line option (tee –a file), which causes tee
 * to append text to the end of a file if it already exists. (Refer to Appendix B for a
 * description of the getopt() function, which can be used to parse command-line
 * options.)
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>

static const size_t buffer_size = 10;

int
main (int argc, char *argv[])
{
  int fd = STDOUT_FILENO;
  int opt;
  while ((opt = getopt (argc, argv, "+:a:")) != -1)
    {
      int file_fd;
      switch (opt)
        {
        case 'a':
          file_fd = open (optarg, O_WRONLY|O_CREAT|O_APPEND,
                          S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);
          if (file_fd != -1)
            fd = file_fd;
          else
            fputs ("Failed to open given file", stderr), _exit (EXIT_FAILURE);
          break;
        default:
          fprintf (stderr, "Unexpected case %c\n", opt);
          _exit (EXIT_FAILURE);
        }
    }

  if (optind < argc)
    {
      int file_fd = open (argv[optind], O_WRONLY|O_CREAT|O_TRUNC,
                          S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);
      if (file_fd != -1)
        fd = file_fd;
      else
        fputs ("Failed to open given file", stderr), _exit (EXIT_FAILURE);
    }

  char buffer[buffer_size];
  ssize_t nbytes_read = 0;
  while ((nbytes_read = read (STDIN_FILENO, buffer, buffer_size)) > 0)
    {
      if (write (fd, buffer, nbytes_read) != nbytes_read)
        {
          exit (EXIT_FAILURE);
        }
    }
  close (fd);

  return EXIT_SUCCESS;
}
